package card;

import effect.Effect;
import effect.EffectGenerator;
import effect.EffectUtil;
import effect.Effect.EffectType;

/**
 * 
 * @author Oscar
 * CreatureCards are the actuall units of the game. These can walk around on the game board, attack 
 * each other etc. The most important Card which the game revolves around.
 */
public abstract class CreatureCard extends Card {
	public enum Race {human, elf, dwarf, greenSkin, troll, dragon, beast, creature, magical, undead, giant};

	protected int maxBaseAttack;
	protected int minBaseAttack;
	protected int baseHealth; 
	protected int baseDefence;
	protected int currentHealth;
	protected int moveRange=1;
	protected int maxActions=1;
	protected int actionsLeft;
	protected Race race;
	
	public enum CreatureSize {small, normal, large, huge};
	protected CreatureSize size;
	
	public int getBaseHealth() {
		return baseHealth;
	}

	public void setBaseHealth(int baseHealth) {
		this.baseHealth = baseHealth;
	}
	
	public int getMaxActions() {
		return maxActions;
	}

	public void setMaxActions(int maxActions) {
		this.maxActions = maxActions;
	}

	public int getActionsLeft() {
		return actionsLeft;
	}

	public void setActionsLeft(int actionsLeft) {
		this.actionsLeft = actionsLeft;
	}

	public Race getRace() {
		return race;
	}

	public void setRace(Race race) {
		this.race = race;
	}

	/**
	 * Constructor setting all base values
	 * 
	 * @param name	Creature name
	 * @param desc	Creature description
	 * @param iB	Big icon
	 * @param iS	Small icon
	 * @param iC	Card icon
	 * @param gC	Gold cost
	 * @param mC	Mana cost
	 * @param maxBA	Maximum base attack value
	 * @param minBA	Minimum base attack value
	 * @param health	Start health
	 * @param bD	Base defense value
	 * @param mR	The amount of tiles the creature can move each turn
	 */
	public CreatureCard(String name, String desc, String iB, String iS, String iC,
			int gC, int mC, int maxBA, int minBA, int health, int bD, int mR) {
		
		super(name, desc, iB, iS, iC, gC, mC);
		
		this.setBaseDefence(bD);
		this.setCurrentHealth(health);
		this.maxBaseAttack = maxBA;
		this.minBaseAttack = minBA;
		this.setMoveRange(mR);
	}
	
	/**
	 * Completely empty constructor.
	 */
	public CreatureCard(){	
		super();
		
		
	}
	

	public void playCard(){
		for(String s : effectsToAddOnSpawn){
			effects.add(EffectGenerator.generateEffect(s));
		}
		currentHealth=getActualMaxHealth();
		actionsLeft=0; // You are not allowed to move and attack the turn you play your card.
	}
	
	//Getters and setters
	
	/**
	 * Might be removed at a later time.
	 * Calculates damage taking effects into consideration
	 * Only used in combat
	 * @return Damage
	 */
	

	public int getMinDmg(){
		int dmg = minBaseAttack;
		for(Effect e : EffectUtil.getSubList(effects, EffectType.damageModifier))
			dmg += e.getAddedMinimumDamage(minBaseAttack);
		return dmg;
	}
	
	public int getMaxDmg(){
		int dmg = maxBaseAttack;
		for(Effect e : EffectUtil.getSubList(effects, EffectType.damageModifier))
			dmg += e.getAddedMaximumDamage(maxBaseAttack);
		return dmg;
	}


	/**
	 * @param health the health to set
	 */
	public void setCurrentHealth(int health) {
		this.currentHealth = health;
	}

	/**
	 * @return the health
	 */
	public int getCurrentHealth() {
		return currentHealth;
	}

	/**
	 * @param moveRange the moveRange to set
	 */
	public void setMoveRange(int moveRange) {
		this.moveRange = moveRange;
	}

	/**
	 * @return the moveRange
	 */
	public int getMoveRange() {
		return moveRange;
	}
	
	public CreatureSize getSize() {
		if(size != null)
			return size;
		else
			return CreatureSize.normal;
	}

	/**
	 * @param baseDefence the baseDefence to set
	 */
	public void setBaseDefence(int baseDefence) {
		this.baseDefence = baseDefence;
	}

	/**
	 * @return the baseDefence
	 */
	public int getBaseDefence() {
		return baseDefence;
	}
	
	public int getActualMaxHealth(){
		//TODO priority 2 Calculate actual maximum health, needs to be able to be modified of abilities or spells
		int h = baseHealth;
		return h;
		
	}
	public int getActualDefense(){
		//TODO priority 2 Calculate actual defense value, needs to be able to be modified of abilities or spells 
		int d=baseDefence;
		for(Effect e : EffectUtil.getSubList(effects, EffectType.defenceModifier))
			d += e.getAddedDefence(baseDefence);
		return d;
	}
	public String getCurrentHealthString(){
		String s = currentHealth + "/" + getActualMaxHealth();
		return s;
	}
	
	public String getActualAttackValueString(){
		
		String s = getMinDmg() + " - " + getMaxDmg();
		return s;
	}

	public String getActualDefenseString() {
		String s = String.valueOf(getActualDefense());
		return s;
	}

	/**
	 * Returns true if the CreatureCard has at least one action left
	 * @return
	 */
	public boolean hasActionLeft(){
		return (actionsLeft > 0);
	}
	/**
	 * Sets amount of actions left to max.
	 */
	public void resetActions(){
		actionsLeft = maxActions;
	}
	/**
	 * Uses one action
	 */
	public void useAction(){
		if(hasActionLeft())
			actionsLeft--;
		else
			System.out.println("Minor Warning. Tried to use an action without having available actions.");
	
	}

	
}
